// 1906.[合并区间/example.map差分数组]服务器空闲时段
// https://oj.rnd.huawei.com/problems/1906/submissions
// 1. 合并同一台机器的空闲时段
// 2. 统计每一台
// =============================
//现有serverNum台服务器和taskNum项任务，并将任务按时段分配给各服务器，
//请你统计恰好有且只有一台服务器空闲的时段（注：“空闲”指没有任务在执行）。
//最后请输出排序后的空闲时段。说明：统计范围的最大时刻为当前用例的涉及的最大时刻。
//须合并连续的时段，如：[1,2]和[2,3]合并为[1,3]。按照时段的开始时刻的大小升序排序。
//若无满足要求的时段，输出区间-1 -1。
//输入 第一行一个整数 serverNum，表示服务器个数，取值范围 [1,10^4)
//第二行一个整数 taskNum，表示任务个数，取值范围 [1,10^4)
//接下来 taskNum 行，每行 3 个整数startTime endTime
// serverId，分别表示一个任务的开始时刻、结束时刻、服务器编号。取值范围：0 <
// startTime < endTime < 10^9， 1 <= serverId <= serverNum 输出
//每行两个整数，表示一个空闲时段，格式为：startTime endTime。 输入 3
// 5
// 1 2 1
// 1 3 1
// 5 6 1
// 2 3 2
// 5 6 3
//输出 2 3
// 5 6
//样例 1 解释，如下图所示：
// 1 号服务器总共分配了 3 项任务，2/3 号服务器各分配了 1 项任务，
//时段 [1, 2]： 1 号服务器在工作，2/3号服务器空闲，
//时段 [2, 3]： 1 号和 2 号服务器在工作，3 号服务器空闲，
//时段 [3, 5]： 3 台服务器都空闲，
//时段 [5, 6]： 1 号和 3 号服务器在工作，2 号服务器空闲，
//故满足要求的时段为 [2, 3] 和 [5, 6]。
//输入 4
// 6
// 1 2 1
// 1 2 2
// 1 2 4
// 2 3 1
// 2 3 2
// 2 3 3
//输出 1 3
// 1/2 号服务器各分配了 2 项任务，3/4 号服务器各分配了 1 项任务，
//时段 [1, 2]： 1/2/4 号服务器在工作，3 号服务器空闲，
//时段 [2, 3]： 1/2/3 号服务器在工作，4 号服务器空闲，
//故满足要求的时段为 [1, 2] 和 [2, 3]，合并后为 [1, 3]
//输入 2
// 3
// 1 3 1
// 1 2 2
// 2 3 2
//输出 -1 -1
//提示 1 号服务器分配了 1 项任务，2 号服务器各分配了 2 项任务，
//时段 [1, 2]： 1/2 号服务器在工作，没有服务器空闲，
//时段 [2, 3]： 1/2 号服务器在工作，没有服务器空闲，
//故没有满足要求的时段，输出[-1, -1]。

#include <algorithm>
#include <iostream>
#include <map>
#include <unordered_map>
#include <vector>
using namespace std;

#define DEBUG
#ifdef DEBUG
#define PF(...) printf(__VA_ARGS__)
#else
#define PF(...)
#endif

class Solution {
  struct Section {
    int begin = 0, end = 0;
  };

 public:
  vector<pair<int, int>> GetOneFreeTime(int serverNum,
                                        const vector<vector<int>> &tasks) {
    map<int, vector<Section>> mapBusyTime;
    auto taskTmp = tasks;
    sort(taskTmp.begin(), taskTmp.end());
    for (auto curTask : taskTmp) {
      int curStart = curTask[0];
      int curEnd = curTask[1];
      int curSvr = curTask[2];
      vector<Section> &vtBusy = mapBusyTime[curSvr];
      //  合并时间段到新vector表, 合并区间
      //   s--------e
      //         s----e  => curTask
      if (vtBusy.empty() || vtBusy.back().end < curStart) {
        vtBusy.push_back({curStart, curEnd});
      } else {
        vtBusy.back().end = max(curEnd, vtBusy.back().end);
      }
    }
    for (auto svr : mapBusyTime) {
      PF("========= svr=%d\n", svr.first);
      for (auto ti : svr.second) PF("%d-%d,   ", ti.begin, ti.end);
      PF("\n");
    }
    // 构建差分数组  diff[i] = a[i] - a[i-1]
    // 对工作服务器的时间段做差分
    map<int, int> timeDiff;  // <timePoint, diff>
    for (auto sever : mapBusyTime) {
      for (auto workTime : sever.second) {
        timeDiff[workTime.begin] += 1;
        timeDiff[workTime.end] -= 1;
      }
    }
    for (auto dif : timeDiff) PF("%d,%d   ", dif.first, dif.second);
    PF("\n");

    vector<pair<int, int>> result;
    int sum = 0;
    bool bWorking = false;
    for (auto diff :
         timeDiff) {  // 用差分还原数组, 找到[恰好有且只有一台空闲],保存时间点
      sum += diff.second;
      if (!bWorking && sum == serverNum - 1) {  // start
        result.push_back({diff.first, 0});
        bWorking = true;
      }
      if (bWorking && sum != serverNum - 1) {
        result.back().second = diff.first;
        bWorking = false;
      }
    }
    return result;
  }
};
// 以下为考题输入输出框架，此部分代码不建议改动
inline int ReadInt() {
  int number;
  std::cin >> number;
  return number;
}
template <typename T>
inline std::vector<T> ReadVector(int size) {
  std::vector<T> objects(size);
  for (int i = 0; i < size; ++i) {
    std::cin >> objects[i];
  }
  return objects;
}
inline void WriteVector(const std::vector<pair<int, int>> &objects) {
  auto it = objects.begin();
  if (it == objects.end()) {
    return;
  }
  std::cout << it->first << ' ' << it->second;
  for (++it; it != objects.end(); ++it) {
    std::cout << endl << it->first << ' ' << it->second;
  }
  std::cout << std::endl;
}
int main() {
  int serverNum = ReadInt();
  int timeDiff = ReadInt();
  vector<vector<int>> tasks(timeDiff);
  for (int i = 0; i < timeDiff; ++i) {
    tasks[i] = ReadVector<int>(3);
  }
  Solution solu;
  auto result = solu.GetOneFreeTime(serverNum, tasks);
  if (result.empty()) {
    cout << "-1 -1";
  } else {
    WriteVector(result);
  }
  return 0;
}
